package win.zxshuo.www.utils;


import java.math.BigInteger;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringUtils {


    /**
     * @usage To Detect String is Only Contain letter number
     * @param strToVerify
     * @return
     */
    public static boolean isNormalString(String strToVerify){
        String strRegex = "^[A-Za-z0-9\\-]+$";
        Pattern pattern = Pattern.compile(strRegex);
        Matcher matcher = pattern.matcher(strToVerify);
        return matcher.find();
    }

    /**
     * 判断是否是url
     * @param strToVerify
     * @return
     */
    public static boolean isUrlString(String strToVerify){
        String strRegex = "^https?://[a-z]*.?[a-z]";
        return true;
    }

    /**
     * 生成随机字符串
     * @param length
     * @return
     */
    public static String randStr(Integer length){
        String Chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int num = random.nextInt(62);
            buf.append(Chars.charAt(num));
        }
        return buf.toString();
    }

    /**
     * 通过md5值加密字符串
     * @param str
     * @return
     * @throws Exception
     */
    public static String md5Str(String str) throws Exception{
        try{
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.update(str.getBytes());
            return new BigInteger(1,messageDigest.digest()).toString(16);
        }catch (Exception e){
            throw new Exception(e);
        }
    }

    /**
     * 通过随机值加密密码
     * @param pwd
     * @return
     * @throws Exception
     */
    public static String encryptPwd(String pwd) throws Exception {
        try {

            String salt = randStr(4);
            String strToEncrypt = pwd + salt;
            String encryptedStr = md5Str(strToEncrypt);
            return encryptedStr+salt;
        }catch (Exception e){
            throw new Exception(e);
        }
    }

    public static String randToken(){
        return randStr(32);
    }

    /**
     * 通过字符串和盐值加密密码
     * @param pwd
     * @param salt
     * @return
     * @throws Exception
     */
    public static String encryptPwd(String pwd,String salt) throws Exception {
        try {
            String strToEncrypt = pwd + salt;
            String encryptedStr = md5Str(strToEncrypt);
            return encryptedStr + salt;
        }catch (Exception e){
            throw new Exception(e);
        }
    }

    /**
     * 比对密码和加密后的密码是否是相同的密码
     * @param pwd
     * @param encryptedPwd
     * @return
     * @throws Exception
     */
    public static boolean comparePwd(String pwd,String encryptedPwd) throws Exception {
        try {
            String salt = encryptedPwd.substring(encryptedPwd.length()-4,encryptedPwd.length());
            System.out.println("salt is "+salt);
            String newEncryptPwd = encryptPwd(pwd,salt);
            System.out.println(newEncryptPwd);
            if (newEncryptPwd.equals(encryptedPwd)){
                return true;
            }else {
                return false;
            }
        }catch (Exception e){
            throw new Exception(e);
        }
    }


    /**
     * @Description:将html字符串的br转换为p
     * @param source
     * @return
     */
    public static String changeBrToP(String source){
        String output = "";
        source = source.replace("<br/>","<br>");
        source = source.replace("<br />","<br>");
        String[] lists = source.split("<br>");
        for (String line:lists){
            String newLine = "";
            String tline = line.trim();
            if (!tline.equals("")){
                newLine = "<p>"+tline+"</p>";
                output = output + newLine;
            }
        }
        return output.replace("&nbsp;","");
    }

    /**
     * @Description 通过文章标题获取标题中的数字
     * @param title
     * @return
     */
    public static Integer getTitleNum(String title){
        String rgex = "第(.*?)章";
        Pattern pattern = Pattern.compile(rgex);
        Matcher matcher = pattern.matcher(title);
        if (matcher.find()){
            Integer orderNum = chineseNumToInt(matcher.group(1));
            return orderNum;
        }
        rgex = "(.*?)章";
        pattern = Pattern.compile(rgex);
        matcher = pattern.matcher(title);
        if (matcher.find()){
            Integer orderNum = chineseNumToInt(matcher.group(1));
            return orderNum;
        }
        rgex = "第(.*?)掌";
        pattern = Pattern.compile(rgex);
        matcher = pattern.matcher(title);
        if (matcher.find()){
            Integer orderNum = chineseNumToInt(matcher.group(1));
            return orderNum;
        }

        return -1;
    }

    /**
     * @Description 改方法能将中文字符串数值转换为Int的数值。如报错，请提供数值字符串我去还原现场，毕竟一个小时的产物，可能思虑不周，请见谅
     * @param num
     * @return
     */
    public static Integer chineseNumToInt(String num){
        System.out.println("num = [" + num + "]");
        Integer resultNum = 0;
        String[] list = num.split("");
        Integer tmpNum = 0;
        Integer mark = 0;
        for (int i =0;  i< list.length;i++ ){
            String str = list[i];
            if (isQuantifier(str)){
                mark = 1;
            }
            if (isCNNumber(str)){
                mark = 0;
            }
            if (mark.equals(0)){
                resultNum = resultNum + tmpNum;
                tmpNum = 0;
                switch (str){
                    case "一":
                        tmpNum = 1;
                        break;
                    case "二":
                        tmpNum = 2;
                        break;
                    case "三":
                        tmpNum = 3;
                        break;
                    case "四":
                        tmpNum = 4;
                        break;
                    case "五":
                        tmpNum = 5;
                        break;
                    case "六":
                        tmpNum = 6;
                        break;
                    case "七":
                        tmpNum = 7;
                        break;
                    case "八":
                        tmpNum = 8;
                        break;
                    case "九":
                        tmpNum = 9;
                        break;
                    case "零":
                        tmpNum = 0;
                        break;
                    case "壹":
                        tmpNum = 1;
                        break;
                    case "贰":
                        tmpNum = 2;
                        break;
                    case "叁":
                        tmpNum = 3;
                        break;
                    case "肆":
                        tmpNum = 4;
                        break;
                    case "伍":
                        tmpNum = 5;
                        break;
                    case "陆":
                        tmpNum = 6;
                        break;
                    case "柒":
                        tmpNum = 7;
                        break;
                    case "捌":
                        tmpNum = 8;
                        break;
                    case "玖":
                        tmpNum = 9;
                        break;
                    default:
                        tmpNum=0;
                        break;
                }
                if (i == list.length-1){
                    resultNum = resultNum + tmpNum;
                }

            }else if (mark.equals(1) || mark.equals(2)){
                if (i==0){
                    tmpNum = 1;
                }
                switch (str){
                    case "圆":
                        tmpNum = tmpNum * 1;
                        break;
                    case "十":
                        tmpNum = tmpNum * 10;
                        break;
                    case "拾":
                        tmpNum = tmpNum  * 10 ;
                        break;
                    case "百":
                        tmpNum = tmpNum * 100;
                        break;
                    case "佰":
                        tmpNum = tmpNum * 100;
                        break;
                    case "千":
                        tmpNum = tmpNum * 1000;
                        break;
                    case "仟":
                        tmpNum  = tmpNum * 1000;
                        break;
                    case "万":
                        tmpNum = tmpNum * 10000;
                        break;
                    case "萬":
                        tmpNum = tmpNum * 10000;
                        break;
                    case "亿":
                        tmpNum = tmpNum * 100000000;
                        break;

                }
                if (i==0){
                    resultNum = resultNum +tmpNum;
                    tmpNum = 0;
                }
                if (i == list.length-1){
                    resultNum = resultNum + tmpNum;
                }

            }
        }
        System.out.println("num = [" + resultNum + "]");

        return resultNum;
    }

    /**
     * 判断是否是中文数字
     * @param str
     * @return
     */
    public static Boolean isQuantifier(String str){
        String[] quantifier = {"圆","十","拾","百","佰","千","仟","万","萬"};
        for (String qStr:quantifier){
            if (qStr.equals(str)){
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否是中文数字
     * @param str
     * @return
     */
    public static Boolean isCNNumber(String str){
        String[] CNNumber = {"玖","捌","柒","陆","伍","肆","叁","贰","壹","零","九","八","七","六","五","四","三","二","一"};
        for (String cnNum:CNNumber){
            if (cnNum.equals(str)){
                return true;
            }
        }
        return false;
    }

    /**
     * 获取域名网址
     * @param url
     * @return
     */
    public static String getBaseUrl(String url){
        String[] strs = url.split("://");
        String protocol = strs[0];
        String domain = strs[1].split("/")[0];
        return protocol+"://"+domain;
    }

    /**
     * 将url处理为完整的URL，注意！要处理的url必须是从baseUrl中获取的，否则会出错！
     * @param urlToDeal
     * @param baseUrl
     * @return
     */
    public static String makeUrlFull(String urlToDeal,String baseUrl){
        if (urlToDeal.startsWith("/")){
            return getBaseUrl(baseUrl)+urlToDeal;
        }else if (urlToDeal.startsWith("http://")){
            return urlToDeal;
        }else if (urlToDeal.startsWith("https://")){
            return urlToDeal;
        }else {
            return baseUrl+urlToDeal; // 例如http://www.baidu.com/23333 这个是baseUrl ,www/www/www 这个是urlToDeal 那么就可以两个组合一起，
        }
    }

    public static String addUrlProtocol(String url,String protocol){
        if (url.startsWith("http")||url.startsWith("https")){
            return url.replace("\r","").replace("\n","");
        }else {
            if (url.startsWith("//")){
                return (protocol+":"+url).replace("\r","").replace("\n","");
            }else {
                return (protocol+"://"+url).replace("\r","").replace("\n","");
            }
        }
    }

    /**
     * 解析ids到列表id
     * @param ids
     * @return
     */
    public static List<Long> parseIdsToIntIds(String ids){
        List<Long> intIds = new ArrayList<>();
        String[] strIds = ids.split(",");
        for (String id:strIds){
            Long tmp = Long.valueOf(id);
            intIds.add(tmp);
        }
        return intIds;
    }


    /**
     * 将时间转为2018-01-01 11:11:11 这种格式
     * @param time
     * @return
     */
    public static String timeToStr(Date time){
        SimpleDateFormat dateFm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFm.format(time);
    }

    /**
     * 转换p到r
     * @param str
     * @return
     */
    public static String parsePtoR(String str){
        str = str.replace("<p>","").replace("&nbsp;","").replace("</p>","\n").replace("&nbsp;","");
        return str;
    }

    public static String[] parsePtoList(String str){
        String[] dealed = str.replace("<p>","").replace("&nbsp;","").split("</p>");
        return dealed;
    }

    public static String translateIntNumToStr(Integer num){
        String word = "";
        if (num>=10000 && num <100000000){
            Integer tmp = num / 10000;
            word = tmp.toString()+"万字";
        }else if (num >100000000){
            Integer tmp = num / 100000000;
            word = tmp.toString()+"亿字";
        }else {
            word = num.toString()+"字";
        }
        return word;
    }


}
